/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package comportamientos;

import jade.core.Agent;

import jade.lang.acl.ACLMessage;
import jade.proto.ContractNetInitiator;
import java.util.ArrayList;
import java.util.Vector;

/**
 * Comportamiento enviar es un comportmaiento iniciador del protoclo
 * contract net; el recibe el mensaje y de acuerdo a las respuestas recibidas
 * ejecuta una respuesta reciproca para ello
 *  @author hayner Benavides Moreno y Jorge Hernan Londoño Echeverri
 */
public class ComportamientoEnviar extends ContractNetInitiator {

    private ArrayList<String> documentos;
    private int numAgentes;


    public ComportamientoEnviar(Agent a, ACLMessage cfp, ArrayList<String> documentos, int numAgentes) {
        super(a, cfp);
        this.documentos = documentos;
        this.numAgentes = numAgentes;
    }
    /**
     * operacion a realizar cuando se tengan todas las respuestas
     * @param responses
     * @param acceptances
     */
    @Override
    protected void handleAllResponses(Vector responses, Vector acceptances) {

        ArrayList<ArrayList<String>> docs = repartirDocumentos(responses);

        for(int i =0 ; i< responses.size(); i++){
            try{
                ACLMessage mensaje = ((ACLMessage)responses.get(i)).createReply();
                if(docs.get(i).size()>0){// si la cantidad de documentos a enviar para un agente son cero se rechaza su oferta

                    mensaje.setPerformative(ACLMessage.ACCEPT_PROPOSAL);
                    mensaje.setContentObject(docs.get(i));
                }
                else{
                    mensaje.setPerformative(ACLMessage.REJECT_PROPOSAL);                    
                }
                myAgent.send(mensaje);
            }
            catch(Exception e){}
        }
        
    }

    @Override
    protected void handleInform(ACLMessage inform) {
        System.out.println("ya empezo el proceso");
    }
    

    @Override
    protected void handleRefuse(ACLMessage refuse) {
        
    }

     /**
      * Repartir documentos es un metodo donde los documentos y los agentes
      * son cruzados y a cada uno se indica los docuemntos a enviarle,el metodo
      * escogido para ello fue de reparticción normal, dando a cada uno
      * una cantidad aproximada emnte igual.
      * @param responses
      * @return
      */
    public ArrayList<ArrayList<String>> repartirDocumentos(Vector responses){

       
        ArrayList<ArrayList<String>> docs = new ArrayList<ArrayList<String>>();
        
        
        for(int i=0; i<this.numAgentes; i++){
            docs.add(new ArrayList<String>());
        }

        //double cantidad =Math.ceil(numDocumentos/numExtractores);
        int indice=0;
        for(String documento : documentos){
            
           // System.out.println("se envio "+documento+" al "+indice);
            docs.get(indice).add(documento);
            indice++;
            
            if(indice == this.numAgentes){
                indice = 0;
            }
        }
//la otra forma, esta esta en espera por problemas de organización
      /*  for(int i =0 ; i< responses.size(); i++){
            try{
                docs.add(new ArrayList<String>());
                System.out.println("valor mensaje: "+((ACLMessage)responses.get(i)).getContentObject().toString());
                int valor = Integer.parseInt(((ACLMessage)responses.get(i)).getContentObject().toString());
                cantidades.add(valor);                
            }
            catch(Exception e){cantidades.add(-1); e.printStackTrace();}
        }
        System.out.println(cantidades.toString());
        int indice_menor=0; //indice del agente con menos documentos en cola
        int menor = 0;
        int numeroAgentes=cantidades.size();



       while(documentos.size()>0){

            for(int i=0;i<numeroAgentes;i++){
                if(documentos.size()>0){break;}

                if(cantidades.get(i)==0){
                    docs.get(i).add(documentos.get(0));                    
                    cantidades.set(i, cantidades.get(i)+1);
                    documentos.remove(0);
                }
                else{
                    if(menor!=0 && menor > cantidades.get(i)){
                        indice_menor = i;
                        menor = cantidades.get(i);
                    }
                    else if(menor == 0){
                        indice_menor = i;
                        menor=cantidades.get(i);
                    }
                }
            }
            if(documentos.size()>0){
                docs.get(indice_menor).add(documentos.get(0));
                cantidades.set(indice_menor, cantidades.get(indice_menor)+1);
                documentos.remove(0);
            }
            System.out.println(cantidades.toString());
        }*/

        return docs;
    }

    public ArrayList<String> getDocumentos() {
        return documentos;
    }

    public void setDocumentos(ArrayList<String> documentos) {
        this.documentos = documentos;
    }

    

}
